package org.qianji.goosql.cond;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.qianji.goosql.field.Field;
import org.qianji.goosql.operator.Comparator;

/**
 * 通用字段、值比较查询条件，支持小于、大于、小于等于、大于等于、等于、不等于、LIKE六个比较运算。
 * 
 * @author gmz
 * 
 */
public class ValueCondition extends AbstractCondition {

	/**
	 * 
	 */
	private static final long serialVersionUID = 7834173510654814000L;

	@SuppressWarnings("serial")
	public static final Set<Comparator> acceptedComparators = new HashSet<Comparator>() {
		{
			add(Comparator.LT);
			add(Comparator.GT);
			add(Comparator.LE);
			add(Comparator.GE);
			add(Comparator.EQ);
			add(Comparator.NE);
			add(Comparator.LIKE);
		}
	};

	private Field field;
	private Comparator comparator;
	private Object value;

	/**
	 * 根据字段、比较运算符、值构造查询条件。
	 * 
	 * @param field
	 *            {@link Field} 字段
	 * @param comparator
	 *            {@link Comparator} 比较运算符，只需是小于、大于、小于等于、大于等于、等于、不等于或LIKE
	 * @param value
	 *            {@link Object} 值
	 */
	public ValueCondition(Field field, Comparator comparator, Object value) {
		super();
		if (field == null || comparator == null || value == null) {
			throw new NullPointerException("args can't be null");
		}
		this.field = field;
		this.comparator = comparator;
		this.value = value;
	}

	/**
	 * 获取字段。
	 * 
	 * @return {@link Field} 字段
	 */
	public Field getField() {
		return field;
	}

	/**
	 * 获取比较运算符。
	 * 
	 * @return {@link Comparator} 比较运算符
	 */
	public Comparator getComparator() {
		return comparator;
	}

	/**
	 * 获取值。
	 * 
	 * @return {@link Object} 值
	 */
	public Object getValue() {
		return value;
	}

	@Override
	public String toSql() {
		StringBuffer cond = new StringBuffer();
		cond.append(field.toSql()).append(" ").append(comparator).append(" ?");
		return cond.toString();
	}

	@Override
	public List<Object> getPlacedParameters() {
		List<Object> ppl = new ArrayList<Object>();
		ppl.addAll(field.getPlacedParameters());
		ppl.add(getValue());
		return ppl;
	}

	@Override
	public Map<String, Object> getNamedParameters() {
		return field.getNamedParameters();
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null || !(obj instanceof ValueCondition)) {
			return false;
		}
		ValueCondition other = (ValueCondition) obj;
		if (field.equals(other.getField()) && comparator.equals(other.getComparator())
				&& value.equals(other.getValue())) {
			return true;
		}
		return false;
	}

	@Override
	public int hashCode() {
		int hc = 37 * 17 + field.hashCode();
		hc = 37 * hc + comparator.hashCode();
		hc = 37 * hc + value.hashCode();
		return hc;
	}

	@Override
	public String toString() {
		return toSql();
	}

}
